home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 42
/
Amiga Format AFCD42 (Issue 126, Aug 1999).iso
/
-serious-
/
programming
/
other
/
gui4cli
/
ext
/
lvformat
/
lvformat.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-14
|
10KB
|
309 lines
/***********************************************************************
*
* LVFormat.c by D. Keletsekis (7/10/98) - dck@hol.gr
*
* This program was made to be used with the CedBar.gc gui, a icon
* bar for the CygnusEd editor. It can, however, be used anywhere
* else too, if you need any of it's funtions.
*
* It creates a port named "LVFormat" and will sit around waiting
* for commands sent from Gui4Cli using the CALL command. It will
* then perform whatever action is required, on the CURRENT listview.
*
* These are the commands you can CALL from Gui4Cli :
*
* Indent [string]
* - Will indent the current listview by whatever "string"
* contains. (Optional - default is 3 spaces).
* ex: CALL LVFormat INDENT ">>>" ; indent by 3 > thingies..
*
* UnIndent
* - Will find the minimum indentation and will move all text
* in by that much.
*
* AGClean
* - Will remove all AmigaGuide formating from the current LV.
*
* WRAP [Length] [Justify] [Header]
* - Will wrap the selected text. The wraping is intelligent
* in that it will try to figure out your indentations and
* wrap the text so that they remain as they were.
* - The options you can give are :
* Length - The length that you want the lines wraped to. The
* default, if you give weird values, is 60.
* Justify - This must be either "" (i.e. nothing) or :
* JUST - meaning justify the text by adding extra
* spaces to make up the line length.
* UNJUST - remove all these extra spaces.
* CENTER - center the text (automatically unjust)
* RESET - remove all extra spacing & indentations.
* Header - a string of characters that wrap should consider
* as part of the line header. This is usefull for
* wrapping email messages etc, by giving ">/" or
* whatever your mailer uses. Spaces are always in.
*
************************************************************************/
// define this for faster exec calls
#define __USESYSBASE
#include <exec/exec.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <dos/dosextens.h>
#include <dos/rdargs.h>
#include <dos/dostags.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <dos.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <graphics/text.h>
// the Gui4Cli include file
#include <Gui4Cli.h> // use "Gui4Cli.h" if you keep it in same dir
// declare a version string (if you want..)
static const char VERSION[] = "\0$VER: LVFormat 1.0 (D.Keletsekis 15/9/98)";
// the prototypes - other includes at end of file..
#include "lvformat_protos.h"
// ===============================================================
// MAIN() - note there is no need for a main() function
// The program starts at the 1st function it finds, which
// can be any name..
// ===============================================================
LONG anyname(void)
{
struct ExecBase *SysBase = (*((struct ExecBase **) 4));
struct DosLibrary *DOSBase=NULL;
struct Process *myself = (struct Process *)(SysBase->ThisTask);
struct MsgPort *myport=NULL; // our port
struct g4cmsg *msg; // Gui4Cli message pointer
int rc = 10; // return code
LONG stayalive = 1; // Quit counter
BOOL msgreplied; // flag
LONG num=60; // default wrap length
SHORT just=0; // justify flag
// -------------------- open the dos library or die..
if (!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36L)))
{ myself->pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
goto endprog;
}
// --------------------- Open message port or die..
if (!(myport = openport ("LVFormat", SysBase, DOSBase)))
{ PutStr ("Couldn't open LVFormat port!\n");
goto endprog;
}
// ---------------------- Main wait() & process loop
while (stayalive > 0)
{
WaitPort (myport);
msg = (struct g4cmsg *)GetMsg(myport);
msgreplied = 0; // flag that message is outstanding
// check that the message is like we expect it..
if ((msg->magic != 392001) || (msg->type != GM_COMMAND) || (!msg->gcmain) || (!msg->com))
{ msg->res = 20; // indicate error
goto endloop; // skip message
}
// --------------- Parse & execute the commands..
// The command name is in msg->com and it's already converted
// into upper case by Gui4Cli.
else if (!strcmp(msg->com, "INDENT")) // Indent [IndentString]
{
// if they sent us an argument..
if (msg->args[0])
indentlist (msg->gcmain, msg->args[0], SysBase, DOSBase);
else // default = indent by 3 spaces
indentlist (msg->gcmain, " ", SysBase, DOSBase);
}
else if (!strcmp(msg->com, "UNINDENT")) // remove all leading spaces
{
unindentlist (msg->gcmain, SysBase, DOSBase);
}
else if (!strcmp(msg->com, "AGCLEAN")) // clear amiga guide stuff
{
agclean (msg->gcmain, SysBase, DOSBase);
}
// WRAP [LineLength] [JUST/UNJUST] [HeaderCharacters]
else if (!strcmp(msg->com, "WRAP"))
{
// get wrap length (default = 60)
if (msg->args[0])
if ((StrToLong(msg->args[0], &num)) <= 0) num = 60;
// get justification mode (just/unjust or nothing)
if (msg->args[1])
{ makeupper(msg->args[1]);
just=0;
if (!strcmp(msg->args[1], "JUST")) just = 1;
else if (!strcmp(msg->args[1], "UNJUST")) just = 2;
else if (!strcmp(msg->args[1], "CENTER")) just = 3;
else if (!strcmp(msg->args[1], "RESET")) just = 4;
}
// args[2] contains the header chars, if any.
rewrap (msg->gcmain, num, msg->args[2], just, SysBase, DOSBase);
}
// Quiting :
// A gui which wants to use us will "Register", so we ++stayalive
// and quit only when all registered guis have told us to quit.
else if (!strcmp(msg->com, "QUIT")) // asked to quit
--stayalive;
else if (!strcmp(msg->com, "REGISTER")) // add a life
++stayalive;
endloop:
if (!msgreplied) ReplyMsg ((struct Message *)msg);
} // end of main while(stayalive) loop
rc = 0; // everything ok..
// ---------------------- END PROG - CLEAN UP
endprog :
if (myport) closeport (myport, SysBase, DOSBase);
if (DOSBase) CloseLibrary((struct Library *)DOSBase);
return (rc);
}
// ================================================================
// create a new public message port
// ================================================================
struct MsgPort *openport (char *portname, struct ExecBase *SysBase, struct DosLibrary *DOSBase)
{
struct MsgPort *port=NULL;
Forbid ();
if ((port = FindPort(portname)) != NULL)
{ // if port already exists - return NULL
port = NULL;
}
else
port = CreatePort (portname, 0);
Permit();
return (port);
}
// ================================================================
// free a public message port
// ================================================================
void closeport (struct MsgPort *port, struct ExecBase *SysBase, struct DosLibrary *DOSBase)
{
struct Message *msg;
Forbid ();
// empty port
while (msg = GetMsg (port))
ReplyMsg (msg);
// remove port name since it's a public msg port
if (port->mp_Node.ln_Name)
RemPort (port);
// delete port
DeleteMsgPort (port);
Permit ();
}
// ==============================================================
// Send a message, wait for reply..
// -->> return 0 for OK or error code otherwise
// - portname = the name of Gui4Cli message port (usually Gui4Cli)
// - type = GM_LOCK, GM_UNLOCK, GM_COMMAND etc..
// - command = the command line or NULL
// ==============================================================
sendmsg (UBYTE *portname, LONG type, UBYTE *command,
struct ExecBase *SysBase, struct DosLibrary *DOSBase)
{
struct Process *myself = (struct Process *)(SysBase->ThisTask);
struct MsgPort *gcport, *myport;
str